// -----------------------------------------------------------------------
//  <copyright file="SettingDefinition.cs" company="LiuliuSoft">
//      Copyright (c) 2022-2024 DaprPlus. All rights reserved.
//  </copyright>
//  <site>https://www.dapr.plus</site>
//  <last-editor>郭明锋</last-editor>
//  <last-date>2024-04-17 14:37</last-date>
// -----------------------------------------------------------------------

using DaprPlus.Domain.Entity;
using DaprPlus.Properties;

using OSharp.Localized;


namespace DaprPlus.Settings.Domain.Entities;

/// <summary>
/// 实体类：设置定义
/// </summary>
[LocalizedDescription("String_Settings_SettingDefinition", typeof(ResDaprPlus))]
public class SettingDefinition : EntityBase, IAggregateRoot
{
    public string Name { get; set; } = null!;

    public string TypeName { get; set; } = null!;

    public string? Remark { get; set; }

    public virtual List<SettingItem> Items { get; set; } = new();

    /// <summary>
    /// 添加或更新设置项
    /// </summary>
    /// <param name="settingItem">设置项</param>
    public void AddOrUpdateItem(SettingItem settingItem)
    {
        if (settingItem == null)
        {
            throw new ArgumentNullException(nameof(settingItem));
        }

        if (string.IsNullOrEmpty(settingItem.Key))
        {
            throw new ArgumentException(@"设置项的Key不能为空", nameof(settingItem));
        }

        // 设置关联关系
        settingItem.SettingDefinitionId = Id;

        // 查找是否已存在相同键的设置项
        var existingItem = Items.FirstOrDefault(x => x.Key == settingItem.Key);

        if (existingItem != null)
        {
            // 检查值是否发生变化，决定是否更新时间戳
            settingItem.LastUpdatedTime = existingItem.ValueJson != settingItem.ValueJson 
                ? DateTime.Now
                // 保持原时间戳
                : existingItem.LastUpdatedTime;

            // 更新现有设置项
            existingItem.ValueJson = settingItem.ValueJson;
            existingItem.ValueTypeName = settingItem.ValueTypeName;
            existingItem.Display = settingItem.Display;
            existingItem.Remark = settingItem.Remark;
            existingItem.Order = settingItem.Order;
            existingItem.IsLocked = settingItem.IsLocked;
            existingItem.LastUpdatedTime = settingItem.LastUpdatedTime;
        }
        else
        {
            // 新设置项，设置当前时间
            settingItem.LastUpdatedTime = DateTime.Now;
            settingItem.SetId();
            // 添加新设置项
            Items.Add(settingItem);
        }
    }

    /// <summary>
    /// 添加或更新设置项（批量）
    /// </summary>
    /// <param name="settingItems">设置项列表</param>
    public void AddOrUpdateItems(IEnumerable<SettingItem> settingItems)
    {
        if (settingItems == null)
        {
            throw new ArgumentNullException(nameof(settingItems));
        }

        foreach (var item in settingItems)
        {
            AddOrUpdateItem(item);
        }
    }

    /// <summary>
    /// 移除设置项
    /// </summary>
    /// <param name="key">设置项键</param>
    /// <returns>是否成功移除</returns>
    public bool RemoveItem(string key)
    {
        if (string.IsNullOrEmpty(key))
        {
            throw new ArgumentException(@"设置项键不能为空", nameof(key));
        }

        var item = Items.FirstOrDefault(x => x.Key == key);
        if (item != null)
        {
            Items.Remove(item);
            return true;
        }

        return false;
    }

    /// <summary>
    /// 获取设置项
    /// </summary>
    /// <param name="key">设置项键</param>
    /// <returns>设置项，如果不存在则返回null</returns>
    public SettingItem? GetItem(string key)
    {
        if (string.IsNullOrEmpty(key))
        {
            throw new ArgumentException(@"设置项键不能为空", nameof(key));
        }

        return Items.FirstOrDefault(x => x.Key == key);
    }

    /// <summary>
    /// 检查是否包含指定键的设置项
    /// </summary>
    /// <param name="key">设置项键</param>
    /// <returns>是否包含</returns>
    public bool ContainsItem(string key)
    {
        if (string.IsNullOrEmpty(key))
        {
            return false;
        }

        return Items.Any(x => x.Key == key);
    }
}
